package com.tinem.platform.web.auth.grant.client_credentials_custom;

import cn.hutool.core.net.NetUtil;
import com.tinem.platform.module.pojo.vo.error.UserException;
import com.tinem.platform.module.starter.jpa.entity.config.ConfigWebAuthIpWhite;
import com.tinem.platform.module.starter.jpa.repository.rbac.ConfigWebAuthIpWhiteRepository;
import com.tinem.platform.module.starter.sdk.MessageCode;
import com.tinem.platform.web.auth.login.LoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Optional;

/**
 * @author fzh
 * @version v1
 * @program: platform
 * @className SmsCodeAuthenticationProvider
 * @description TODO
 * @site 
 * @company 
 * @create 2020-10-01 17:16
 */
@Slf4j
@Component
public class ClientCredentialsCustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private LoginService loginService;

    @Resource(name = "tokenService")
    private ResourceServerTokenServices resourceServerTokenServices;

    @Autowired
    ConfigWebAuthIpWhiteRepository configWebAuthIpWhiteRepository;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        ClientCredentialsCustomAuthenticationToken authenticationToken = (ClientCredentialsCustomAuthenticationToken) authentication;
        Optional<ConfigWebAuthIpWhite> configWebAuthIpWhiteOptional = configWebAuthIpWhiteRepository.findById(authenticationToken.getClientId());
        if(!configWebAuthIpWhiteOptional.isPresent()){
            log.error("ip:{}; not in white:{};",authenticationToken.getIp(),authenticationToken.getClientId());
            throw new UserException(MessageCode.ERROR_PLATFORM_CLOUD_WEB_AUTH_CLIENT_IP);
        }
        ConfigWebAuthIpWhite configWebAuthIpWhite = configWebAuthIpWhiteOptional.get();
        String[] ipWhite = configWebAuthIpWhite.getIpWhite().split(";");
        boolean isWhiteIp = false;
        for (String cidr : ipWhite){
            if(NetUtil.isInRange(authenticationToken.getIp(),cidr)){
                isWhiteIp = true;
                log.debug("ip:{}; cidr:{}",authenticationToken.getIp(),cidr);
            }
        }
        if(!isWhiteIp){
            log.error("ip:{}; not in white:{};",authenticationToken.getIp(),configWebAuthIpWhite.getIpWhite());
            throw new UserException(MessageCode.ERROR_PLATFORM_CLOUD_WEB_AUTH_CLIENT_IP);
        }
        authenticationToken.setAuthenticated(true);
        return authenticationToken;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return ClientCredentialsCustomAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
